﻿#include "MdbIndexes.h"
#include "MdbTables.h"
#include "Utility.h"
#include <string.h>


namespace mdb
{
	TickIndexInstrumentID::TickIndexInstrumentID(TickTable* table)
		:m_Table(table)
	{
	}
	TickIndexInstrumentID::iterator TickIndexInstrumentID::LowerBound(const InstrumentIDType& InstrumentID)
	{
		FillCompareRecord(InstrumentID);
		std::shared_lock guard(m_Table->m_SharedMutex);
		return m_Index.lower_bound(&t_CompareTick);
	}
	TickIndexInstrumentID::iterator TickIndexInstrumentID::UpperBound(const InstrumentIDType& InstrumentID)
	{
		FillCompareRecord(InstrumentID);
		std::shared_lock guard(m_Table->m_SharedMutex);
		return m_Index.upper_bound(&t_CompareTick);
	}
	std::pair<TickIndexInstrumentID::iterator, TickIndexInstrumentID::iterator> TickIndexInstrumentID::EqualRange(const InstrumentIDType& InstrumentID)
	{
		FillCompareRecord(InstrumentID);
		std::shared_lock guard(m_Table->m_SharedMutex);
		return m_Index.equal_range(&t_CompareTick);
	}
	void TickIndexInstrumentID::Insert(Tick* const record)
	{
		m_Index.insert(record);
	}
	void TickIndexInstrumentID::Erase(Tick* const record)
	{
		auto it = FindNode(record);
		m_Index.erase(it);
	}
	void TickIndexInstrumentID::Update(iterator it)
	{
		auto record = *it;
		m_Index.erase(it);
		m_Index.insert(record);
	}
	bool TickIndexInstrumentID::NeedUpdate(const Tick* const oldRecord, const Tick* const newRecord)
	{
		return !(TickEqualForInstrumentIDIndex()(oldRecord, newRecord));
	}
	TickIndexInstrumentID::iterator TickIndexInstrumentID::FindNode(Tick* const record)
	{
		auto p = m_Index.equal_range(record);
		for (auto it = p.first; it != p.second; ++it)
		{
			if (*it == record)
			{
				return it;
			}
		}
		return m_Index.end();
	}
	void TickIndexInstrumentID::FillCompareRecord(const InstrumentIDType& InstrumentID)
	{
		Strcpy(t_CompareTick.InstrumentID, InstrumentID);
	}

	BarIndexInstrumentID::BarIndexInstrumentID(BarTable* table)
		:m_Table(table)
	{
	}
	BarIndexInstrumentID::iterator BarIndexInstrumentID::LowerBound(const Int64Type& TradingDay, const ExchangeIDType& ExchangeID, const InstrumentIDType& InstrumentID)
	{
		FillCompareRecord(TradingDay, ExchangeID, InstrumentID);
		std::shared_lock guard(m_Table->m_SharedMutex);
		return m_Index.lower_bound(&t_CompareBar);
	}
	BarIndexInstrumentID::iterator BarIndexInstrumentID::UpperBound(const Int64Type& TradingDay, const ExchangeIDType& ExchangeID, const InstrumentIDType& InstrumentID)
	{
		FillCompareRecord(TradingDay, ExchangeID, InstrumentID);
		std::shared_lock guard(m_Table->m_SharedMutex);
		return m_Index.upper_bound(&t_CompareBar);
	}
	std::pair<BarIndexInstrumentID::iterator, BarIndexInstrumentID::iterator> BarIndexInstrumentID::EqualRange(const Int64Type& TradingDay, const ExchangeIDType& ExchangeID, const InstrumentIDType& InstrumentID)
	{
		FillCompareRecord(TradingDay, ExchangeID, InstrumentID);
		std::shared_lock guard(m_Table->m_SharedMutex);
		return m_Index.equal_range(&t_CompareBar);
	}
	void BarIndexInstrumentID::Insert(Bar* const record)
	{
		m_Index.insert(record);
	}
	void BarIndexInstrumentID::Erase(Bar* const record)
	{
		auto it = FindNode(record);
		m_Index.erase(it);
	}
	void BarIndexInstrumentID::Update(iterator it)
	{
		auto record = *it;
		m_Index.erase(it);
		m_Index.insert(record);
	}
	bool BarIndexInstrumentID::NeedUpdate(const Bar* const oldRecord, const Bar* const newRecord)
	{
		return !(BarEqualForInstrumentIDIndex()(oldRecord, newRecord));
	}
	BarIndexInstrumentID::iterator BarIndexInstrumentID::FindNode(Bar* const record)
	{
		auto p = m_Index.equal_range(record);
		for (auto it = p.first; it != p.second; ++it)
		{
			if (*it == record)
			{
				return it;
			}
		}
		return m_Index.end();
	}
	void BarIndexInstrumentID::FillCompareRecord(const Int64Type& TradingDay, const ExchangeIDType& ExchangeID, const InstrumentIDType& InstrumentID)
	{
		t_CompareBar.TradingDay = TradingDay;
		Strcpy(t_CompareBar.ExchangeID, ExchangeID);
		Strcpy(t_CompareBar.InstrumentID, InstrumentID);
	}

	BarIndexTradingDay::BarIndexTradingDay(BarTable* table)
		:m_Table(table)
	{
	}
	BarIndexTradingDay::iterator BarIndexTradingDay::LowerBound(const Int64Type& TradingDay)
	{
		FillCompareRecord(TradingDay);
		std::shared_lock guard(m_Table->m_SharedMutex);
		return m_Index.lower_bound(&t_CompareBar);
	}
	BarIndexTradingDay::iterator BarIndexTradingDay::UpperBound(const Int64Type& TradingDay)
	{
		FillCompareRecord(TradingDay);
		std::shared_lock guard(m_Table->m_SharedMutex);
		return m_Index.upper_bound(&t_CompareBar);
	}
	std::pair<BarIndexTradingDay::iterator, BarIndexTradingDay::iterator> BarIndexTradingDay::EqualRange(const Int64Type& TradingDay)
	{
		FillCompareRecord(TradingDay);
		std::shared_lock guard(m_Table->m_SharedMutex);
		return m_Index.equal_range(&t_CompareBar);
	}
	void BarIndexTradingDay::Insert(Bar* const record)
	{
		m_Index.insert(record);
	}
	void BarIndexTradingDay::Erase(Bar* const record)
	{
		auto it = FindNode(record);
		m_Index.erase(it);
	}
	void BarIndexTradingDay::Update(iterator it)
	{
		auto record = *it;
		m_Index.erase(it);
		m_Index.insert(record);
	}
	bool BarIndexTradingDay::NeedUpdate(const Bar* const oldRecord, const Bar* const newRecord)
	{
		return !(BarEqualForTradingDayIndex()(oldRecord, newRecord));
	}
	BarIndexTradingDay::iterator BarIndexTradingDay::FindNode(Bar* const record)
	{
		auto p = m_Index.equal_range(record);
		for (auto it = p.first; it != p.second; ++it)
		{
			if (*it == record)
			{
				return it;
			}
		}
		return m_Index.end();
	}
	void BarIndexTradingDay::FillCompareRecord(const Int64Type& TradingDay)
	{
		t_CompareBar.TradingDay = TradingDay;
	}

}
